{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Generative Adversarial Networks (GANs)\n",
    "到目前为止，在CS231N中，我们已经探索过的所有神经网络应用都是**判别模型**，它接受输入并训练生成标记输出。从简单的图像分类到句子生成(这仍然是一个分类问题，我们的标签在词汇空间中，我们学习了一个递归式来捕获多词标签)。在这个笔记本中，我们将扩展我们的repetoire算法，并使用神经网络构建生成模型。具体来说，我们将学习如何建立模型，产生新的即时通讯\n",
    "### What is a GAN?\n",
    "\n",
    "In 2014, [Goodfellow et al.](https://arxiv.org/abs/1406.2661) presented a method for training generative models called Generative Adversarial Networks (GANs for short). In a GAN, we build two different neural networks. Our first network is a traditional classification network, called the **discriminator**. We will train the discriminator to take images, and classify them as being real (belonging to the training set) or fake (not present in the training set). Our other network, called the **generator**, will take random noise as input and transform it using a neural network to produce images. The goal of the generator is to fool the discriminator into thinking the images it produced are real.\n",
    "\n",
    "We can think of this back and forth process of the generator ($G$) trying to fool the discriminator ($D$), and the discriminator trying to correctly classify real vs. fake as a minimax game:\n",
    "$$\\underset{G}{\\text{minimize}}\\; \\underset{D}{\\text{maximize}}\\; \\mathbb{E}_{x \\sim p_\\text{data}}\\left[\\log D(x)\\right] + \\mathbb{E}_{z \\sim p(z)}\\left[\\log \\left(1-D(G(z))\\right)\\right]$$\n",
    "where $z \\sim p(z)$ are the random noise samples, $G(z)$ are the generated images using the neural network generator $G$, and $D$ is the output of the discriminator, specifying the probability of an input being real. In [Goodfellow et al.](https://arxiv.org/abs/1406.2661), they analyze this minimax game and show how it relates to minimizing the Jensen-Shannon divergence between the training data distribution and the generated samples from $G$.\n",
    "\n",
    "To optimize this minimax game, we will aternate between taking gradient *descent* steps on the objective for $G$, and gradient *ascent* steps on the objective for $D$:\n",
    "1. update the **generator** ($G$) to minimize the probability of the __discriminator making the correct choice__. \n",
    "2. update the **discriminator** ($D$) to maximize the probability of the __discriminator making the correct choice__.\n",
    "\n",
    "While these updates are useful for analysis, they do not perform well in practice. Instead, we will use a different objective when we update the generator: maximize the probability of the **discriminator making the incorrect choice**. This small change helps to allevaiate problems with the generator gradient vanishing when the discriminator is confident. This is the standard update used in most GAN papers, and was used in the original paper from [Goodfellow et al.](https://arxiv.org/abs/1406.2661). \n",
    "\n",
    "In this assignment, we will alternate the following updates:\n",
    "1. Update the generator ($G$) to maximize the probability of the discriminator making the incorrect choice on generated data:\n",
    "$$\\underset{G}{\\text{maximize}}\\;  \\mathbb{E}_{z \\sim p(z)}\\left[\\log D(G(z))\\right]$$\n",
    "2. Update the discriminator ($D$), to maximize the probability of the discriminator making the correct choice on real and generated data:\n",
    "$$\\underset{D}{\\text{maximize}}\\; \\mathbb{E}_{x \\sim p_\\text{data}}\\left[\\log D(x)\\right] + \\mathbb{E}_{z \\sim p(z)}\\left[\\log \\left(1-D(G(z))\\right)\\right]$$\n",
    "\n",
    "### What else is there?\n",
    "Since 2014, GANs have exploded into a huge research area, with massive [workshops](https://sites.google.com/site/nips2016adversarial/), and [hundreds of new papers](https://github.com/hindupuravinash/the-gan-zoo). Compared to other approaches for generative models, they often produce the highest quality samples but are some of the most difficult and finicky models to train (see [this github repo](https://github.com/soumith/ganhacks) that contains a set of 17 hacks that are useful for getting models working). Improving the stabiilty and robustness of GAN training is an open research question, with new papers coming out every day! For a more recent tutorial on GANs, see [here](https://arxiv.org/abs/1701.00160). There is also some even more recent exciting work that changes the objective function to Wasserstein distance and yields much more stable results across model architectures: [WGAN](https://arxiv.org/abs/1701.07875), [WGAN-GP](https://arxiv.org/abs/1704.00028).\n",
    "\n",
    "\n",
    "GANs are not the only way to train a generative model! For other approaches to generative modeling check out the [deep generative model chapter](http://www.deeplearningbook.org/contents/generative_models.html) of the Deep Learning [book](http://www.deeplearningbook.org). Another popular way of training neural networks as generative models is Variational Autoencoders (co-discovered [here](https://arxiv.org/abs/1312.6114) and [here](https://arxiv.org/abs/1401.4082)). Variatonal autoencoders combine neural networks with variationl inference to train deep generative models. These models tend to be far more stable and easier to train but currently don't produce samples that are as pretty as GANs.\n",
    "\n",
    "Here's an example of what your outputs from the 3 different models you're going to train should look like... note that GANs are sometimes finicky, so your outputs might not look exactly like this... this is just meant to be a *rough* guideline of the kind of quality you can expect:\n",
    "\n",
    "![caption](gan_outputs_pytorch.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:38:12.404911Z",
     "start_time": "2020-02-26T12:38:12.374012Z"
    }
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "from torch.nn import init\n",
    "from torch.autograd import Variable\n",
    "import torchvision\n",
    "import torchvision.transforms as T\n",
    "import torch.optim as optim\n",
    "from torch.utils.data import DataLoader\n",
    "from torch.utils.data import sampler\n",
    "import torchvision.datasets as dset\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.gridspec as gridspec\n",
    "\n",
    "%matplotlib inline\n",
    "plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots\n",
    "plt.rcParams['image.interpolation'] = 'nearest'\n",
    "plt.rcParams['image.cmap'] = 'gray'\n",
    "\n",
    "def show_images(images):\n",
    "    images = np.reshape(images, [images.shape[0], -1])  # images reshape to (batch_size, D)\n",
    "    sqrtn = int(np.ceil(np.sqrt(images.shape[0])))\n",
    "    sqrtimg = int(np.ceil(np.sqrt(images.shape[1])))\n",
    "\n",
    "    fig = plt.figure(figsize=(sqrtn, sqrtn))\n",
    "    gs = gridspec.GridSpec(sqrtn, sqrtn)\n",
    "    gs.update(wspace=0.05, hspace=0.05)\n",
    "\n",
    "    for i, img in enumerate(images):\n",
    "        ax = plt.subplot(gs[i])\n",
    "        plt.axis('off')\n",
    "        ax.set_xticklabels([])\n",
    "        ax.set_yticklabels([])\n",
    "        ax.set_aspect('equal')\n",
    "        plt.imshow(img.reshape([sqrtimg,sqrtimg]))\n",
    "    return \n",
    "\n",
    "def preprocess_img(x):\n",
    "    return 2 * x - 1.0\n",
    "\n",
    "def deprocess_img(x):\n",
    "    return (x + 1.0) / 2.0\n",
    "\n",
    "def rel_error(x,y):\n",
    "    return np.max(np.abs(x - y) / (np.maximum(1e-8, np.abs(x) + np.abs(y))))\n",
    "\n",
    "def count_params(model):\n",
    "    \"\"\"Count the number of parameters in the current TensorFlow graph \"\"\"\n",
    "    param_count = np.sum([np.prod(p.size()) for p in model.parameters()])\n",
    "    return param_count\n",
    "\n",
    "answers = np.load('gan-checks-tf.npz')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dataset\n",
    "GANs是出了名的讲究超参数，也需要很多的训练时间。为了让这项任务在没有GPU的情况下也可以完成，我们将使用MNIST数据集，它包含6万张训练图和1万张测试图。每张图片都包含一幅以白色数字为中心的图像，背景为黑色(0到9)。这是第一批用于训练卷积神经网络的数据集之一，非常简单——一个标准的CNN模型可以轻松地超过99%的准确率。\n",
    "\n",
    "为了简化这里的代码，我们将使用PyTorch MNIST包装器，它下载并加载MNIST数据集\n",
    "\n",
    "See the [documentation](https://github.com/pytorch/vision/blob/master/torchvision/datasets/mnist.py) for more information about the interface. The default parameters will take 5,000 of the training examples and place them into a validation dataset. The data will be saved into a folder called `MNIST_data`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:38:18.398348Z",
     "start_time": "2020-02-26T12:38:14.393081Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqoAAAJkCAYAAADZZwOuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOydeaBU4//HX1chpdWWtRCKkApJWSNbWUqkTZYSEQpfFaUsibIkogVJtqTIUpEsRYTsUWRtUdIihdTvj/m9zzP33Jm7zplzzu3z+mfqztyZ57nnzFnez/vz/uRs3rwZwzAMwzAMw4gaW4U9AMMwDMMwDMNIhV2oGoZhGIZhGJHELlQNwzAMwzCMSGIXqoZhGIZhGEYksQtVwzAMwzAMI5LYhaphGIZhGIYRScrm92ROTk6pyq7avHlzTvL/bX7xwuYXb2x+8cbmF29sfvFmS5tfMqaoGoZhGIZhGJHELlQNwzAMwzCMSGIXqoZhGIZhGEYksQtVwzAMwzAMI5LYhaphGIZhGIYRSexC1TAMwzAMw4gk+cZTGZmlQYMGAHTv3h2Ajh07MnbsWACGDRsGwMcffxzO4AzDiAX33XcfAFdddRUAX3zxBQBnnHEGAD/++GM4AzOMDPPGG28AkJOTSC464YQTQhvLgQceCLjvWZcuXQD48MMPAfjkk09yvf7ee+/ln3/+yeIISy+mqBqGYRiGYRiRJGfz5vSZsUEFypYpUwaAypUrp3xeimP58uU54IADALjiiisAuPvuuwFo27YtABs2bABg0KBBANxyyy1pPzeswNx69eoBMGPGDAAqVaqU5zWrV68GYIcddij258QhEPjEE08E4MknnwTg2GOPBeCbb74p8HejOL++ffsCbr/baqvEvd9xxx0HwFtvvVXo94ri/DJJ2POrWLEiANtvvz0Ap59+OjvttBMAQ4cOBeDvv/8u9vsHPb+aNWsC8NFHHwFQpUoVfS6QmA/A1KlTM/mxHkHPb//99wdg6623BuCYY44B4MEHHwRg06ZNBb7H5MmTATj//PMBiqRoZWv/1PwaN24MwO233w7A0UcfHcTHeYT9/SsK99xzDwCXXXYZgLfy2LVr17S/E+T8unbt6l176PhRECeccAJvvvlmpoYQq+1XHCzw3zAMwzAMw4gdgXlU99prLwC22WYbIHH32KRJE8ApAa1atSrwfX755RcA7r//fgDOPvtsANauXQvAp59+ChRNucoWRxxxBADPP/884BRkKSBr16717vilpDZq1AhwXtWgPC5SK/S5L7zwQiCf4+fwww8HnK8nzlx44YXccMMNQF61J7+VCiM7SIHUNjrqqKMAqFu3bp7X7rrrroDzfUaR5cuXA/D2228D0LJlyzCHkxEOOuggIPFdOvfccwG3KrHbbrsB7rtVmO+U/iYjRowA4OqrrwZgzZo1GRx1ydB5QGrb0qVLAahevXqu/2+JaGVUSuq///4LOK9qWDz33HMMGDAAKLyiOnHiRM477zwApk2bFtjYtgRMUTUMwzAMwzAiScYVVb8fM50PtTBs2rTJ8wD++eefgPM2LlmyBIA//vgDKJzHMWjKly8PQP369QEYN24c4NQaPwsWLGDw4MEAPP300wDMmjULcN7HO+64I5CxykO53377AcErqlJJ9t57bwBq1KgBuGrOOFKjRg3KlSsX9jCKzJFHHglA+/btAecTlrolevXqxeLFiwG81RDt03PmzMnKWItC7dq1AaeitWvXDoDtttsOcPvazz//DCRWNOrUqQNAmzZtAOeHnD9/fpZGXXjWrVsHlK6qfh3fTjvttIy+b8eOHQEYPXo04I6rUURKqimqbkVRPt53330XgGeffTa0MQGsXLmSfv36ATBkyBDAne9/+uknwK0iiypVqnDKKacAW46iqvO6jrmqJerWrZv3mpdffhmAzp07F/p9TVE1DMMwDMMwIknGFVXdXfz+++9A4RRVqTOrVq0C4PjjjwcS/swnnngi00MMjIcffhhwdxEFUb9+fc/vIo+tlM5DDjkk8wNMQorDe++9F+jnCKnKl156KeCUuSgqVwXRrFkzAK688krvZ5qHMvaWLVuW/YEVgPxSyuHccccdAac0zpw5E8CrhL/rrru839Vr9JyqqsNGx5c777zTm5+q+/0sWLAAgObNmwMJ1UbbTX8LPUYRefsPPfTQkEeSOaZPnw7kVlR/++03wKmhWo3x+8AbN27srQbEmTivKqVC9Q99+vQB3Plw5cqVaX9Hr5F//LvvvgMSqzpRQb5n+Wf1PczP//zAAw8EP7AQ0bnwnHPOAdx29NfjJCPVvCiYomoYhmEYhmFEkowrqrpruu666wCnMH3yySde5b6YN28eACeddBLgPFjyyvXo0SPTwwuMBg0aeDmG/jtkqaUvvfQS4LJgFy9e7HWzkNdWnTeCvsuWSpEtRo0alev/UrfihHyajz76KJB7tUDqY9T8g2XLJr7iDRs2ZOTIkYDzVql6fODAgYDzg2277bZAwhd28skn53q/uXPnBj/oIqAUkEsuuSTta6TO6Dgjj2qtWrUCHl1m0Xbze+GEEjWkEkdtX0zFQw89BMCkSZO8n6nSuyCvZqVKlbyuXEoIEHq/qO2vqZDqFEe/eyoeeeQRwNU/qKOTji+p6N27N+BSaLTyplSfKHHrrbcCTjFWXU4qlHpUmtC5/OCDD/aOOX6UyqSaIqX8PPXUU172fVEwRdUwDMMwDMOIJIHlqOqOVtX/a9eu9TwdF198MeCURSmp4ssvvwRcL90oo7up6dOnex2ndIf86quvAs63IT+VKvpHjRrlZSPqzlE+LKmzShBQrmomOOSQQ9hll10y9n6Fwe9VljctTnTq1AnIrd7I16nOKVFDlf3Jirb+9vJ0+j1W+nmymqo848cffzy4wRYDZW8m88MPPwDuLl45qlJShSr+44ISGB577DEA+vfvn+t5/V9e/zj44zZu3Ajk3TaFoXnz5lStWjXlc9pfS9JpLNs0bNgQgPfffz/kkZSMv/76CyicUqzzp6rFdf6Lsro8YcIEwCnEqug/+OCD87xW6mvr1q2zNLrMI5VbCR0XXXQRkFg9V5c85d9qhWP9+vWAq1kqKYFdqIrkk6DahArJ+8888wxQuBZ5UUHt/mRxqFy5MitWrABcdJZO6orWUiyDHvND8Q49e/YEXNROJjjttNO89w8aXRArlkr8+uuvWfn8TKACG31BtZ+uWrXKOxBFDS3na0lt8+bNXvSSbpTSFQFoSSsZBeHrxioq6BjSpUsX74SxcOFCwBXlpCPbN2uZQtvWf6G6paBCvksvvTTtcezmm2/O5pCKhC7OdT7UTfy+++4b2pgygfZLXbB9/fXXQPrl+woVKng3kbK16CJdF4NRROdiCW+pGoiI/OwOceGmm24CnMA4bNgwIHGe0LVN0NjSv2EYhmEYhhFJAldUk5EC0KBBA8AthSviIA6huCo0kW1BsSpr1671Ip9k4M+EapmucKIkHHDAAd6/ZbMICv2dpF59++23gDNbRxm14FQLXD/Dhg3z2iBGBSlJUlLVgnfq1KmeeqFlGaFlNi31a5/LycnxFOPJkycHPPLioeXw4qiLaqkaV9LFNpU2pGD973//A1wRnELhk1GBrgqyooisGe+88w7gCo7jzJ577umtbkgx7t69O5B+FWbo0KGedUff46OPPjrooRaL2rVre01xtP+pUDU/XnzxxUDHlUmkaus80aFDB8A1UNG5burUqQDFKooqLqaoGoZhGIZhGJEkq4qqiqZ056UCIcXm6IpdiuTw4cNTBsaGyWGHHQbkbfl35plnejFUcUIFJ5lAxWRqG9e+ffs88UbyMUlViDKah7/5whtvvAG44PwooDD4yy+/HHCFDLr7Peuss/L8jpQBRYhopUNMmDDBa/EbR+SrrVChQsrnk4sfZs+eDWSvAUYmkJIatWNkUdCqRYcOHbyVNT+KhUs1T/mspba+8sorQN5VAyMY5M984YUXPC+/PIzpzocK8b/wwgu9n912220BjrLk1KlTx6uzKIySKq655hogd3OYqKLaBSmqalurle5sKqh+TFE1DMMwDMMwIklWFVWhAG7dUSlAXZ4IPVaoUMGL/VElfdgMHToUcIH8umvMlJqabd9ZtWrV8n1elY05OTme4rHHHnsALsxYHjKNXWrGnDlzvHgY3YUqziLKSH1U5IZQBadiqvwpFmGibeFvASpVceedd6Zz584AtGzZEnBqiNr4SrHS47hx4/JEx0WV8uXLe8Hi/fr1A/KueqT6bskbp7/Nf//9F/hYDbfvycNXXC++fJ4KmY8zigGKMjqOK/Yuuc2tvlfyft94442AO2fqXCNfak5Ojnd+V/vxqPLCCy9w/fXXA4l2zVC4CC21Do8D2l46/j/11FNAuEqqMEXVMAzDMAzDiCShKKpCVXRqp6k7rxNPPBGA22+/3QsCloclrPxNVWYqoFh3HZmu6vP7zlTFmknWr1/vvf+IESMAVyXuR/7MnJwcr5pTgc5fffUVAGPGjAGct1jq8rJly7zgbSUgqL1jFCmoyv/7778HEvOKGqruV4XtTjvtBMCiRYuA1P4+qYny+enuX3nAavkbRVTxLc/4888/741fir7mJ9+pPMeqbgWnEJ1zzjmA8x3r72kEi1am8msZnd8qk47Lp556KuCarMQRrXREGWXYqoGIjiubNm3y8ovVuECPZ555JgC777474I4zy5cv97Kp44BawOt6RXUBQscSNdpQzUZc+OCDDwC33TQPHU/DbNJjiqphGIZhGIYRSUJVVIXabrVp0waAFi1aAAnvateuXQHYb7/9ADjppJNCGKFTBOUFVNcbddUqLspl9edAqvWsfCOZ5PLLL+fHH38EoHHjxvm+Vi3QJk2a5HUaKWyLvy5dunjKntTIKKNqx3T+YL9nNUooRUH+2ilTpgDOF/bdd995Wahqwbly5UoAnn76acApHfp/FNH3T+roxIkTveduueUWwH13Zs2aBbi/gX6e3ElG+6faAybv7xDtFpzplMZjjjkGiHYLVR3zjzvuOCDheSxsPqM65MShkjo/lHIThxxVtVVWPYlyanXcueCCC/jjjz8AGDJkCOBy0qXQSTWXCrvjjjt6rXO1H6h+JcqkU+01P6Wp3HzzzXlaxOq8GzZHHnkkAJ988gmQWEHSqoTqGtSRSl3C9DthrIqaomoYhmEYhmFEkkgoqkJ3Z0888QSQ8MHI9yGVQHdeM2fOzPr4kpHSUpI0gm233dbLLrvuuusAPE+n7kqD6qWrysUgkdcY0vs+o0K9evXyZL4KKZHffPNNNodULObMmQM4pTA/9J2S8iFlLorqtzypUk31fRGvvvqql9+o44j+BsrWVG6q/KeDBw/21FX56JQp+/rrrwPueyK1CILxjReHdDmq8tseeOCBno88qkhhKkqOplaf4q6oSr0X2sejpr4B3sqmxqyOdVJYk9F2USV/ug5wOTk5nqocByW1ILTao+6A4JTnsNNEtFqmlTalbCjnddy4cd4Km1ZipKgqFaaghKAgicSFqgp2WrduDcDhhx8O5A7W1QH37bffzvLoUlOSIiotB1x33XXekoouhlq1alXywUUQFc5FlWnTplG1atVcP5PFITmYujQhO4v/gidKS/9lypQBXKMIhYUrNktB708//bR3geovBlDBlYogunXrBiSWXlXwIAuMotZU2OIvIPj555+94O+wUSGkLiL8dOnSxWt/WJpo3rx52EPICCpOFVo6lh0sSuj8JKuNluxToYi8ZIsNQNu2bQFn+wAnzJQGdPGejOK7wp6nmivpeCeb27hx4/K8tkePHrn+r5v25O2WbWzp3zAMwzAMw4gkoSiqBxxwAADdu3cH3FJV9erV87xWkrmW2LMVhO/HH6OiohX/3Ud+SGaXpF65cmVvqbFjx44ZG6tRdHbYYYc8+9aDDz4IBGe/CBsVr0SZLl26AE5JVTSaVES192vUqJEX2q+iACnGAwYMANwyZbIapGiu1157Ldej1J8LLrgg13j0HY4CUY5686NlbdlrVNhWlFan2r5Ral1cEqRSajvWrl0bwFPB1Q45ChTmb165cmXABfpLvdOyvlpyRhE1W9AxQmH3eswPLavrWJVMcrFnmChaS1ZD/V+P4FacVLgu64kKunWsDANTVA3DMAzDMIxIkjVFtXr16p5KISVVAevpmDt3rmeyz3SwflHxt5eU+qs7kjFjxvD7778DCXUHXCtYtSFV61EZ0qdOneqpdqUVKdD7778/UPhoq2yhO2hF/SQze/bsbA8nq8TB65dcmADOs6piKhXWKBImGT2n6KmiFDQURVEJCxWPqXhl3333zfV8jx49vNeEVazSpEkTAPr06QO4eEH5fPPzOqp4Q61w1RAmuWGDFNkotHksLloVUCD+tddeG+Zwio0UYHnAFeF4wgknhDamwqLzuKIxdb5S05Bff/3Va2jQoEGDXK9Ra1V/wP+QIUO83w8bHQNV3CXfvtqiA16Nxssvvwy4VSzNO0xMUTUMwzAMwzAiSWCK6i677AIkIlIgUYErD046FK1z1113AQkPT1ie1IKQsqO7yFatWnkeDnk8/EihUySHXy0qjUiBTqVYhomSF3RHuWnTJi+2aPjw4UA0W6Vmkn322SfsIRTI0qVLARc1pYporVKIV155xUsEUVj/Dz/8AIQfDRM0X375JZB3e0bh2KnkBX8FuFSotWvXpv1dqa/169cH8sZwzZw5k4ceeghwx9Q4o/nFsX1vjRo1uOSSSwA3j0ceeQQIv+K9MGjlQUq/IrUUg/nDDz94yUNNmzYFoGLFirneQ/OW57hfv36RU/rvvvvusIdQLKJ19WAYhmEYhmEY/0/GFFX5iRTyK8UqP9VGCqPC7VWFXJRK0Gzx3nvvAfDhhx8CLutVVK9e3VORhTyryqUsSkJAaUN3qGrfGTZVqlQBcidN/Prrr4Dz5pR23nnnHSB9K84ooKYEStmQuib/25gxY4BEIH8clahMIOVK/ro4IB9jUdA2f+mll4DE8TRqilVJkMdRzSeinj2dzPTp071GBcrm7NevX5hDKhKqndB5Xk2HVENSs2bNAmtq1BREq8hG5jBF1TAMwzAMw4gkxVZUjzzySMBV3x5xxBGAq1xMhTIQVWF3++23A67LTJSRz0aZr8pxVC5ZMsqck38qClVzYaGqfyN6qNOI8vO0+qHq8eXLl4czsCTkYZTCoUfDIe/c119/DUCdOnXCHE4u1NVNyQSdOnUq8HeUUKDzhZR/KcdhdsgJgjZt2gCuLbe2Y5x49NFHve5xyoeNIz179gScF17tQ8FVyiu9SKxevRpwnmoj85iiahiGYRiGYUSSHH8lZa4nc3LSPjlo0CDAKap+dJc/ZcoUINHXWF5U9eTONps3b84l7+U3vzgStfldeOGFnodw5MiRQPq+5IUhk/OTN/WZZ54BEnmPixYtAlJncmaDsLafVK9Ro0YB8NZbbwEJFUzf40wQtf0z09j80iOFSvua+qIru3HSpElMnz4dcIqcEh+yRVjbTzUMUsJbtmwJuM5AmcL2z3izpc0vmWJfqMaRLW1D2/ziRVjzUxGHWhwqsmvixIle28pM2HNs+8Ubm1+8sfnFmy1tfsnY0r9hGIZhGIYRSUxRLUXY/OJN2POTsqq2xd26deOQQw4ByIgFIOz5BY3NL97Y/OKNzS/emKJqGIZhGIZhxA5TVEsRNr94Y/OLNza/eGPzizc2v3hjiqphGIZhGIYRO/JVVA3DMAzDMAwjLExRNQzDMAzDMCKJXagahmEYhmEYkaRsfk+WdrOuzS9e2Pzijc0v3tj84o3NL95safNLxhRVwzAMwzAMI5LYhaphGIZhGIYRSexC1TAMwzAMw4gk+XpUjWDYf//9AXjttdcoU6YMADVq1AhzSIZhGIZhGJHDFFXDMAzDMAwjkpiimkWGDRsGwHnnnQdAtWrVmDJlSphDMgyjlLHPPvsAcMcdd3D22WcDcMghhwAwf/780MZlGIZRHOxCNUB22WUXACZOnAhAo0aNAFA3sC+++IKLL744nMEZhlGqaNy4MZCwFAEsX76c4cOHA7Bs2bLQxmUUj/33358RI0YA0K5dOwCWLFkS5pAyynHHHccbb7wBwFZbbeX9DOCtt94Ka1hGBLGlf8MwDMMwDCOSFEtR3X777b3l6w0bNgDQoEEDACpWrAi4O8CZM2cC8Ouvv6Z9v6VLlwIwefJkAObOnVucYUUGFUvdfffdABx55JG5nr/xxhuBxDx///337A6uBOTkJPJ4n3rqKQBOO+00AA488EAAfvnll3AGZhSKDh06AHDyyScDUK9ePQAOOOCAXK97//33AWjRogWrV6/O4gjDo0KFCoA7Xu22224AHH300QD88MMPYQyrUJx++ukATJgwAcBT4fr06cNff/0V2rhKKxUrVmT77bcH8L4fQfydTzvtNI455hgALrnkEiBh5wDYuHFjxj8vW1x44YUAXHnllWzatCnXc0OHDgVg7NixAN6KQJznW5rRtcxtt90GwODBgwH43//+l9HPMUXVMAzDMAzDiCQ58kumfDJNi67BgwfTq1evjA9Gd1dfffUVkFDupN5lQtHIVgsyeVHffffdXD+XItm+fXvAKZOZIuj5lS9fHoBvvvkGgN133x2ALl26ADBq1KhMflwetrQWcpmY34477ggktk2LFi0AWLVqFQCzZ8/O9Vr5w6Quzp8/31PLM0HY208q6U477eT97I8//gDg+OOPB+DRRx8F3D5+xBFHALB27doC3z/b86tVqxYAn376KQDvvPMO4FY6/GpVSQl7+wVNYec3cOBAT0m67rrrALjnnnsyPp4mTZp4Cr+oXbs2AAsXLizy+4W9/aSkamVHajE4j6p/n9U+/uOPPxb4/mHPTxGT11xzDQCXX345ZcsmFq2ffvppAC644IJiv3/Y8/NTsWJF7zipepx///0XgCuuuAKA0aNHF/r9rIWqYRiGYRiGETuK5VE955xz0j4nz+Vnn32W9jW6Cpc3rkqVKgAcdthhANStWxdI+B70PlH2iAl5U8ePHw84BVXo7yYvbtyQD2vBggWAU1STFarSTM+ePQHYZpttAKhTp47nxRaK/znooIOyO7g0qAK8Zs2ann/orrvuAmDlypW5Xiu15oMPPgAS+/PNN98MwIABA7Iy3pKg48ZVV10F5G2ioe/nXnvt5f1s0KBBgPNZ6zsrT722dZQoV64c4FYwPv/8cwDatGkDZF5JDYtq1aoBLs6vd+/egFPGAfr27Qs472a26devHwDff/89kNlje/Xq1TP2XtlE53N54LVKodUd7b/gjpdSVPUdjROdO3cG4N577wXc+bFr167sueeegNtPdByNc0ycVOJu3bp5SqpQush7772X0c80RdUwDMMwDMOIJMVSVJs3b+7d+Xz77be5npPqVpS8NyUFSBlIVjxatmwJwMsvv1ycoWYVeW80/ldeeQWAyy67DMg/+SBOqBJTnsY6deqEOJrMc+yxxwJOodP/FZ6erJT7Pd777bcf4HzWmfR4FoWTTjoJcKsUzz77rOerS4fu8qUM9O3b11ML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q9CLN2z7xRubX8GofaaW+ceMGQPAyJEj+eWXX0o8xpJg2y/e2PzijSmqhmEYhmEYRuwwRbUUYfOLNza/eGPzizc2v3hj84s3pqgahmEYhmEYsSNfRdUwDMMwDMMwwsIUVcMwDMMwDCOS5NtCtbR7IGx+8cLmF29sfvHG5hdvbH7xZkubXzKmqBqGYRiGYRiRxC5UDcMwDMMwjEhiF6qGYRiGYRhGJLELVcMwDMMImYEDBzJw4EA2b97M5s2b+fHHH9l+++3Zfvvtwx6aYYSKXagahmEYhmEYkSTfqv9s89RTTwHQqFEjAM4//3zmzJkT5pAMwzAMI+OUKVMGgJtuugmAnj17AvDaa68BMGfOHPbZZx8APvvssxBGaBjRIFItVGfPng3AUUcdBcDChQs58MADAfj3339L/P7Zindo1aoVAOXKlQOgYcOGAFx99dUAvPnmmwCMHj2ar7/+GoCPP/64xJ+7pcVX2Pzihc0v3tj8Mku7du0AeOKJJwAYNGgQAL179w7k82z7xZstbX7J2NK/YRiGYRiGEUkioajuueeeAHz33XcAbL311t5z5cuXB2D9+vUl/pwg7ki22247AA444AAGDhwIwIknngjAtttuW+DvL1q0CIAZM2YAcMMNNwCwZs0aAP77779Cj2VLu+PK5Py22247mjdvDkC/fv0AqFevnj435e9cfPHF/PHHH7l+tnDhQgC++OKLIo+hOPM766yzALjyyisBOP744/W7es88vzNp0iQAXn31VQCmTZsGwA477ADAt99+C8Cff/5Z1Cnki+2f8Sbb89Nqmlaidt11VwDOOOMMACZPnuytwolHHnkEgFWrVhX587I1vyOOOAKAl19+GYAff/wRgKOPPhqAv//+O4iPtf0zILRi+uGHHwKwadOmPK/ROeXWW28t9udsadsvGVNUDcMwDMMwjEgSCUW1bt26AHz++ee5fj5p0iTP75nqLqWoZOKO5JBDDgGgadOmAJ4Kd/rpp5d4fMnccsstAEycOBEonEIXtTuuvfbai/feew9wf6fiKI2iJPM74IADAKdY+ylfvjznnntusccmvvzySwBat24NOHWyMBRlflJSx44dC0CFChWKOFLHggULALd6sWLFCgD++ecf7zXXXnstQB4FqyhEbf/MNDa/zDJ06FAAevToUejf0QpHnz59AHj44YcL/bvZmt+Y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pk2bAKhevTovvvgiAC+99BIA55xzTmjjMhLUrFkTgAEDBgDQrl07wG23o48+OpRxBYX2wRYtWgBw+eWXA/DQQw+FNqZMctBBBwFQtmzuw93atWv5/vvvc/2sfPnyAHTo0AEwRdUwjNxopU3HxwYNGgDw22+/ATB//nwAJkyYwNdffw3AH3/8ke1hlipMUTUMwzAMwzAiSSiK6r777gvA+PHjAahQoULK1z355JPeXUocqVKlCgAPPvggAE2bNk372g8//DArYzIKZujQoQCceeaZuX7+77//AvDKK69kfUxBsM022wBORZRi3KNHDyDx/VuzZk04gysBO+ywAwD33nsvAK1atQJg2223BWDz5kTnwZUrV3LEEUekfI8ffvgh4FEaBVGjRg0Axo4dC7jjp7ZfTk6Op1gdd9xxQHge/yeeeAJw+82kSZOK/B4//fQTYHUKUUfHSa223HbbbQCcfvrpgDvOtGvXzlNfGzVqBMB3332X1bEGTf/+/XP9Xx7//Dj++OMBmDlzZqE/xxRVwzAMwzAMI5Lk6O405ZM5OemfLAH3338/AFdccUXK52fMmAFAt27dWLhwYcY+d/PmzTnJ/w9qfkIpBmPGjAFg7733BtwdWSpat24NwOTJk4v8ecWZX7ly5QDYaaedcv1cPsycnMRb7rfffgV+vhTHcePGAYlUg//++6/A3yssQW+//fffH3CKqbaXUGV4UL7FbO+flSpVAuD1118HnNdK7Lbbbixbtixjnxf0/Jo0aQK4u3ypbEmfp3F4P6tXrx7gVneqV68OwAEHHAAUzVuW7e2n+ey6664AnHvuuYA7huy7776ekiO1riRka361a9cGnFKllQ3/9svJyfH+PX36dMDVPRSHksxPK2L169fPM0b9P9X4k///888/A7BixQog4ZOW3zETZGv7aYV04sSJAJx88slA3vPesmXLGD16dK6fjRo1CoAff/yxyJ8b5PyqVq3qHU923HFHwHnfr7zySgD+/vtvwHn9f/jhB958803A1djUqVOn2GPI9vElHTq+FkY9zQ/t/8I/v2RMUTUMwzAMwzAiSVY9qnfddRcA5513Xr6vO+mkk7IxnMCpWrUqkN6Dm4qHH34YcHefSgMIisceewyANm3aZOw9pYS8+OKLXHzxxQD8/vvvGXv/INhll13SKqmitPmItY/5Ve+BAwcC8apU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DjkEgGnTpgHw77//Jv3e/5ohsM2veLbbbjsAZs2aRZcuXTJ67y677MK3335b0iE42Pbzl6ZNmwIwfPhwAE466SSNA4C1a9dy4403AjBx4sQSf59tv/B5/fXXAZg6dSoA9957b9afFfb8KlasCMBzzz0HwMEHHxz3/LfffkvdunUB+Oeff0r8fbnafipUvOqqqwDo2rUrAE2aNHGu288++ywAs2fPzvp7wpqf5vPggw8CcMABBwCw8847F3nt8uXLAdhnn31K/L1m+G8YhmEYhmHkHZaj6iNSSnv27AkUrqjAVTj++OMPwM31ePbZZ7n99tvjnpMCMnjwYACnGGLOnDkA/PLLLyUep4ouADp37gzAoYceCsCFF15Y7PuVyyjrG/3/77//LvHYDH+oWrUq4G6bWDVVq+Bx48YBcOWVVwJQv379uM+45557nH11woQJwQ44YnzzzTcA1KhRI+7xfv36cf/99+diSA41a9YE4NVXXwXic/7A3Z5Tp07lq6++ysEIDVG+fHmgMKr23nvvZfTeevXq0bx5c4C8yhXX9UXnDK+SeueddwJw8803+6Kkhk29evUAaN26NQAXXXQR4BaL6XpfUFBA3759AZy/v/76K+AqrFGidu3aQGH0DeDAAw8s9j077LADAOeddx4A06dPB/y5T4nFFFXDMAzDMAwjkmSVo1qjRg1nNS/Fb/LkyVkP4uyzzwbclYiUyblz5/L9998D8OijjwLw/PPPZ/09Qed4bL311gD8+eefAI6aIZVy/fr1ALz55pvOe1SVu3nz5rjnWrVqBUCbNm0AVwVLRbrzKygowLvd9f/ff/897nFtC+WtJGL16tWAWx34+eefFzvWbAgrR0f79AknnABA//79AahTp07c68qUKeP8bo888gjg5iVnqp6Av/M755xzgPjcRK12lQ+t3MYzzjgj6ecoJ1pG8TfffHO2Qwp8+5UrVw6AY489FoAVK1YA8MEHH6T9GSeffDLgns90TOs81LNnz7jjN5ag56f98OKLLwbcPPZVq1YBcNdddwFuVMZvopjD6SdBzK9Pnz4ANGvWzDne0qVRo0YsW7YMcLf9lClTsh5LWNtPiv/XX38d97juGY488kjArcfwiyDn17x5cycCJeVUaqKYN28eAM888wxQGCWVA4fyyZcsWQLAQQcdlPEYgt5+r732GgBt27bN+jOk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JG+KaoMGDbw74ubNmwPQokWLQv8XuoNOzus6//zzgegqqmPHjuVf//pXod8999xzAFx88cUpX7N06VLvzl/+VlXchY3usPTzhx9+8HxEM2fOTPma9u3bA6k9SGWBBg0aAM7LCfDrr78CTnmLMsomvP766zM+b926dUBCRVWG3ptvvhns4PKA1FKpCJdccomXc3jQQQcBcPzxxxd6ze233w44X7IRDE2bNi2iVAl5A1NVEstPp2NOkyZNAKf4r169OudjzRXyqB511FEAzJ07N8zhBIYyNv3neXCV87/99ls+h1Rszj33XC9VQ/ucVhCvvvrqlK+59tpr8zO4UvDZZ58BziMM8NRTT2X12jp16hRRVIPCFFXDMAzDMAwjkgSmqF5++eWAu1I/4IADPEXV341CfPrpp4C7ypdnFeCxxx4LaqilIrliWp5bKalt27bN+NrHH3+cOXPmAE650d9m/vz5gMslyzdjx44FnC/srrvu4ocffkj53F133RVwiqrQHMoKUm2UHwvQq1cvAJYvXx7KmLJl3LhxRZTuP//8E3CKwMKFCwGnQn388cd5HGHuKF++PAAHHngg4LabKlLlcUwm3THpiCOOCGycWyLyr++3334AXjZz27Zt2XHHHVO+xr9tNmzYACRWpPR+qjLWNpYfO4qKqtI25NXUmMuaoirft84hfn7//XemTp3q/TuKKIVn+PDh3v4n32nv3r1DG1euyVZFBdhll10AuPPOO4s8ps5Us2fPzs3A/h9TVA3DMAzDMIxIEpiiOnjwYMDd6Sajq24pj1JL169fD7iuTMmKqt4vasjDucMOO3h3XJrX5rj44ot54403AKhevTrgVAN5rcJC+WfKhMuEFCpV/7/88suA8/CUFfyKz88//8yqVatCGk3xOPTQQz3FXyj/L47bSX5T3d3XqFGD7t27A06pUrpBaXjyySdL/R4GXHTRRYDzRyu/MRNSrv744w/AKY46T8yaNcurKpbPU8fTKH4vlRyh750sUQPdAAAgAElEQVRU33RKctzR9/Cuu+4q9Puff/4ZSHjmn3322byPqziokr9ixYreOVFJOFL2tzTUcbJly5be71TXoJVh1W7kisAuVLXsrSIFcC3/tKOmQxeqBQUFXtB9VJdWNb6ZM2d6y4QyGL/22muAszT4eeWVV7yoKhHVC/Jk6tatC7j2roqx0M6p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\n",
      "text/plain": [
       "<Figure size 864x864 with 128 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "class ChunkSampler(sampler.Sampler):\n",
    "    \"\"\"Samples elements sequentially from some offset. \n",
    "    Arguments:\n",
    "        num_samples: # of desired datapoints\n",
    "        start: offset where we should start selecting from\n",
    "    \"\"\"\n",
    "    def __init__(self, num_samples, start=0):\n",
    "        self.num_samples = num_samples\n",
    "        self.start = start\n",
    "\n",
    "    def __iter__(self):\n",
    "        return iter(range(self.start, self.start + self.num_samples))\n",
    "\n",
    "    def __len__(self):\n",
    "        return self.num_samples\n",
    "\n",
    "NUM_TRAIN = 50000\n",
    "NUM_VAL = 5000\n",
    "\n",
    "NOISE_DIM = 96\n",
    "batch_size = 128\n",
    "\n",
    "mnist_train = dset.MNIST('./cs231n/datasets/MNIST_data', train=True, download=True,\n",
    "                           transform=T.ToTensor())\n",
    "loader_train = DataLoader(mnist_train, batch_size=batch_size,\n",
    "                          sampler=ChunkSampler(NUM_TRAIN, 0))\n",
    "\n",
    "mnist_val = dset.MNIST('./cs231n/datasets/MNIST_data', train=True, download=True,\n",
    "                           transform=T.ToTensor())\n",
    "loader_val = DataLoader(mnist_val, batch_size=batch_size,\n",
    "                        sampler=ChunkSampler(NUM_VAL, NUM_TRAIN))\n",
    "\n",
    "\n",
    "imgs = loader_train.__iter__().next()[0].view(batch_size, 784).numpy().squeeze()\n",
    "show_images(imgs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 随机噪声\n",
    "使用形状' [batch_size, dim] '从-1到1生成均匀的噪声。\n",
    "\n",
    "Hint: use `torch.rand`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:39:30.188837Z",
     "start_time": "2020-02-26T12:39:30.183851Z"
    }
   },
   "outputs": [],
   "source": [
    "def sample_noise(batch_size, dim):\n",
    "    \"\"\"\n",
    "    Generate a PyTorch Tensor of uniform random noise.\n",
    "\n",
    "    Input:\n",
    "    - batch_size: Integer giving the batch size of noise to generate.\n",
    "    - dim: Integer giving the dimension of noise to generate.\n",
    "    \n",
    "    Output:\n",
    "    - A PyTorch Tensor of shape (batch_size, dim) containing uniform\n",
    "      random noise in the range (-1, 1).\n",
    "    \"\"\"\n",
    "    return torch.rand((batch_size,dim))*2-1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "确保噪音是正确的形状和类型:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:39:47.360446Z",
     "start_time": "2020-02-26T12:39:47.350501Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "All tests passed!\n"
     ]
    }
   ],
   "source": [
    "def test_sample_noise():\n",
    "    batch_size = 3\n",
    "    dim = 4\n",
    "    torch.manual_seed(231)\n",
    "    z = sample_noise(batch_size, dim)\n",
    "    np_z = z.cpu().numpy()\n",
    "    assert np_z.shape == (batch_size, dim)\n",
    "    assert torch.is_tensor(z)\n",
    "    assert np.all(np_z >= -1.0) and np.all(np_z <= 1.0)\n",
    "    assert np.any(np_z < 0.0) and np.any(np_z > 0.0)\n",
    "    print('All tests passed!')\n",
    "    \n",
    "test_sample_noise()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Flatten\n",
    "回想一下我们以前的笔记本电脑中的Flatten操作…这一次我们还提供了一个Unflatten，您可能希望在实现卷积生成器时使用它。我们还提供了一个使用Xavier初始化而不是PyTorch的统一默认值的权值初始化器(并为您调用它)。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:43:27.317867Z",
     "start_time": "2020-02-26T12:43:27.308902Z"
    }
   },
   "outputs": [],
   "source": [
    "class Flatten(nn.Module):\n",
    "    def forward(self, x):\n",
    "        N, C, H, W = x.size() # read in N, C, H, W\n",
    "        return x.view(N, -1)  # \"flatten\" the C * H * W values into a single vector per image\n",
    "    \n",
    "class Unflatten(nn.Module):\n",
    "    \"\"\"\n",
    "    An Unflatten module receives an input of shape (N, C*H*W) and reshapes it\n",
    "    to produce an output of shape (N, C, H, W).\n",
    "    \"\"\"\n",
    "    def __init__(self, N=-1, C=128, H=7, W=7):\n",
    "        super(Unflatten, self).__init__()\n",
    "        self.N = N\n",
    "        self.C = C\n",
    "        self.H = H\n",
    "        self.W = W\n",
    "    def forward(self, x):\n",
    "        return x.view(self.N, self.C, self.H, self.W)\n",
    "\n",
    "def initialize_weights(m):\n",
    "    if isinstance(m, nn.Linear) or isinstance(m, nn.ConvTranspose2d):\n",
    "        init.xavier_uniform(m.weight.data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CPU / GPU\n",
    "By default all code will run on CPU. GPUs are not needed for this assignment, but will help you to train your models faster. If you do want to run the code on a GPU, then change the `dtype` variable in the following cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:44:05.992877Z",
     "start_time": "2020-02-26T12:44:05.988880Z"
    }
   },
   "outputs": [],
   "source": [
    "# dtype = torch.FloatTensor\n",
    "dtype = torch.cuda.FloatTensor ## UNCOMMENT THIS LINE IF YOU'RE ON A GPU!\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 判别器\n",
    "我们的第一步是建立一个鉴别器。作为“nn”的一部分填充架构。下面函数中的顺序构造函数。所有完全连接的层应该包括偏置项。架构是:\n",
    "* 全连接层从784到256\n",
    "* LeakyReLu为0.01\n",
    "* 完全连接层从256到256\n",
    "* LeakyReLu为0.01\n",
    "* 完全连接层从256到1\n",
    " \n",
    "Recall that the Leaky ReLU nonlinearity computes $f(x) = \\max(\\alpha x, x)$ for some fixed constant $\\alpha$; for the LeakyReLU nonlinearities in the architecture above we set $\\alpha=0.01$.\n",
    " \n",
    "The output of the discriminator should have shape `[batch_size, 1]`, and contain real numbers corresponding to the scores that each of the `batch_size` inputs is a real image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:49:45.367894Z",
     "start_time": "2020-02-26T12:49:45.361910Z"
    }
   },
   "outputs": [],
   "source": [
    "def discriminator():\n",
    "    \"\"\"\n",
    "    Build and return a PyTorch model implementing the architecture above.\n",
    "    \"\"\"\n",
    "    model = nn.Sequential(\n",
    "        nn.Flatten(),\n",
    "        nn.Linear(784,256),\n",
    "        nn.LeakyReLU(0.01),\n",
    "        nn.Linear(256,256),\n",
    "        nn.LeakyReLU(0.01),\n",
    "        nn.Linear(256,1)   \n",
    "    )\n",
    "    return model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "确认鉴别器参数数量正确的测试:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:49:59.286211Z",
     "start_time": "2020-02-26T12:49:59.277233Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Correct number of parameters in discriminator.\n"
     ]
    }
   ],
   "source": [
    "def test_discriminator(true_count=267009):\n",
    "    model = discriminator()\n",
    "    cur_count = count_params(model)\n",
    "    if cur_count != true_count:\n",
    "        print('Incorrect number of parameters in discriminator. Check your achitecture.')\n",
    "    else:\n",
    "        print('Correct number of parameters in discriminator.')     \n",
    "\n",
    "test_discriminator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 生成器\n",
    "现在建设生成器网络:\n",
    "* 全连接层，从noise - dim到1024\n",
    "* ReLU\n",
    "* 大小为1024的全连接层\n",
    "* ReLU\n",
    "* 大小为784的全连接层\n",
    "* 双曲正切\n",
    " * 剪切图像为[-1,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:52:23.699391Z",
     "start_time": "2020-02-26T12:52:23.694388Z"
    }
   },
   "outputs": [],
   "source": [
    "def generator(noise_dim=NOISE_DIM):\n",
    "    \"\"\"\n",
    "    Build and return a PyTorch model implementing the architecture above.\n",
    "    \"\"\"\n",
    "    model = nn.Sequential(\n",
    "        nn.Linear(noise_dim,1024),\n",
    "        nn.ReLU(),\n",
    "        nn.Linear(1024,1024),\n",
    "        nn.ReLU(),\n",
    "        nn.Linear(1024,784),\n",
    "        nn.Tanh()\n",
    "    )\n",
    "    return model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "确认生成器参数数量正确的测试:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T12:53:06.320670Z",
     "start_time": "2020-02-26T12:53:06.298736Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Correct number of parameters in generator.\n"
     ]
    }
   ],
   "source": [
    "def test_generator(true_count=1858320):\n",
    "    model = generator(4)\n",
    "    cur_count = count_params(model)\n",
    "    if cur_count != true_count:\n",
    "        print('Incorrect number of parameters in generator. Check your achitecture.')\n",
    "    else:\n",
    "        print('Correct number of parameters in generator.')\n",
    "\n",
    "test_generator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# GAN Loss\n",
    "\n",
    "Compute the generator and discriminator loss. The generator loss is:\n",
    "$$\\ell_G  =  -\\mathbb{E}_{z \\sim p(z)}\\left[\\log D(G(z))\\right]$$\n",
    "and the discriminator loss is:\n",
    "$$ \\ell_D = -\\mathbb{E}_{x \\sim p_\\text{data}}\\left[\\log D(x)\\right] - \\mathbb{E}_{z \\sim p(z)}\\left[\\log \\left(1-D(G(z))\\right)\\right]$$\n",
    "Note that these are negated from the equations presented earlier as we will be *minimizing* these losses.\n",
    "\n",
    "**HINTS**: You should use the `bce_loss` function defined below to compute the binary cross entropy loss which is needed to compute the log probability of the true label given the logits output from the discriminator. Given a score $s\\in\\mathbb{R}$ and a label $y\\in\\{0, 1\\}$, the binary cross entropy loss is\n",
    "\n",
    "$$ bce(s, y) = y * \\log(s) + (1 - y) * \\log(1 - s) $$\n",
    "\n",
    "A naive implementation of this formula can be numerically unstable, so we have provided a numerically stable implementation for you below.\n",
    "\n",
    "You will also need to compute labels corresponding to real or fake and use the logit arguments to determine their size. Make sure you cast these labels to the correct data type using the global `dtype` variable, for example:\n",
    "\n",
    "\n",
    "`true_labels = Variable(torch.ones(size)).type(dtype)`\n",
    "\n",
    "Instead of computing the expectation, we will be averaging over elements of the minibatch, so make sure to combine the loss by averaging instead of summing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T13:04:58.602347Z",
     "start_time": "2020-02-26T13:04:58.594369Z"
    }
   },
   "outputs": [],
   "source": [
    "def bce_loss(input, target):\n",
    "    \"\"\"\n",
    "    Numerically stable version of the binary cross-entropy loss function.\n",
    "\n",
    "    As per https://github.com/pytorch/pytorch/issues/751\n",
    "    See the TensorFlow docs for a derivation of this formula:\n",
    "    https://www.tensorflow.org/api_docs/python/tf/nn/sigmoid_cross_entropy_with_logits\n",
    "\n",
    "    Inputs:\n",
    "    - input: PyTorch Variable of shape (N, ) giving scores.\n",
    "    - target: PyTorch Variable of shape (N,) containing 0 and 1 giving targets.\n",
    "\n",
    "    Returns:\n",
    "    - A PyTorch Variable containing the mean BCE loss over the minibatch of input data.\n",
    "    \"\"\"\n",
    "    neg_abs = - input.abs()\n",
    "    loss = input.clamp(min=0) - input * target + (1 + neg_abs.exp()).log()\n",
    "    return loss.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T13:14:53.134440Z",
     "start_time": "2020-02-26T13:14:53.127465Z"
    }
   },
   "outputs": [],
   "source": [
    "def discriminator_loss(logits_real, logits_fake):\n",
    "    \"\"\"\n",
    "    Computes the discriminator loss described above.\n",
    "    \n",
    "    Inputs:\n",
    "    - logits_real: PyTorch Variable of shape (N,) giving scores for the real data.\n",
    "    - logits_fake: PyTorch Variable of shape (N,) giving scores for the fake data.\n",
    "    \n",
    "    Returns:\n",
    "    - loss: PyTorch Variable containing (scalar) the loss for the discriminator.\n",
    "    \"\"\"\n",
    "    real_labels = torch.ones_like(logits_real).type(dtype)\n",
    "    fake_labels = 1-real_labels\n",
    "    loss_dis =bce_loss(logits_real,real_labels)\n",
    "    loss_gen =bce_loss(logits_fake,fake_labels)\n",
    "    loss=loss_dis+loss_gen\n",
    "    return loss\n",
    "\n",
    "def generator_loss(logits_fake):\n",
    "    \"\"\"\n",
    "    Computes the generator loss described above.\n",
    "\n",
    "    Inputs:\n",
    "    - logits_fake: PyTorch Variable of shape (N,) giving scores for the fake data.\n",
    "    \n",
    "    Returns:\n",
    "    - loss: PyTorch Variable containing the (scalar) loss for the generator.\n",
    "    \"\"\"\n",
    "    fake_labels = torch.ones_like(logits_fake).type(dtype)\n",
    "    loss_gen =bce_loss(logits_fake,fake_labels)\n",
    "    loss=loss_gen\n",
    "    return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Test your generator and discriminator loss. You should see errors < 1e-7."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T13:15:07.922725Z",
     "start_time": "2020-02-26T13:15:04.288353Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Maximum error in d_loss: 3.97058e-09\n"
     ]
    }
   ],
   "source": [
    "def test_discriminator_loss(logits_real, logits_fake, d_loss_true):\n",
    "    d_loss = discriminator_loss(Variable(torch.Tensor(logits_real)).type(dtype),\n",
    "                                Variable(torch.Tensor(logits_fake)).type(dtype)).data.cpu().numpy()\n",
    "    print(\"Maximum error in d_loss: %g\"%rel_error(d_loss_true, d_loss))\n",
    "\n",
    "test_discriminator_loss(answers['logits_real'], answers['logits_fake'],\n",
    "                        answers['d_loss_true'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T13:15:10.811007Z",
     "start_time": "2020-02-26T13:15:10.801034Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Maximum error in g_loss: 4.4518e-09\n"
     ]
    }
   ],
   "source": [
    "def test_generator_loss(logits_fake, g_loss_true):\n",
    "    g_loss = generator_loss(Variable(torch.Tensor(logits_fake)).type(dtype)).data.cpu().numpy()\n",
    "    print(\"Maximum error in g_loss: %g\"%rel_error(g_loss_true, g_loss))\n",
    "\n",
    "test_generator_loss(answers['logits_fake'], answers['g_loss_true'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 优化我们的损失\n",
    "创建一个返回' optim '的函数。Adam的优化器对于给定的模型具有1e-3的学习率，beta1=0.5, beta2=0.999。您将使用它来为生成器构造优化器，并为笔记本的其余部分构造鉴别器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T13:16:05.535320Z",
     "start_time": "2020-02-26T13:16:05.531319Z"
    }
   },
   "outputs": [],
   "source": [
    "def get_optimizer(model):\n",
    "    \"\"\"\n",
    "    Construct and return an Adam optimizer for the model with learning rate 1e-3,\n",
    "    beta1=0.5, and beta2=0.999.\n",
    "    \n",
    "    Input:\n",
    "    - model: A PyTorch model that we want to optimize.\n",
    "    \n",
    "    Returns:\n",
    "    - An Adam optimizer for the model with the desired hyperparameters.\n",
    "    \"\"\"\n",
    "    optimizer = optim.Adam(model.parameters(),betas=(0.5,0.999))\n",
    "    return optimizer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Training a GAN!\n",
    "\n",
    "们为您提供主要的培训循环…您不需要更改这个函数，但是我们鼓励您通读并理解它"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T13:17:14.833642Z",
     "start_time": "2020-02-26T13:17:14.821674Z"
    }
   },
   "outputs": [],
   "source": [
    "def run_a_gan(D, G, D_solver, G_solver, discriminator_loss, generator_loss, show_every=250, \n",
    "              batch_size=128, noise_size=96, num_epochs=10):\n",
    "    \"\"\"\n",
    "    Train a GAN!\n",
    "    \n",
    "    Inputs:\n",
    "    - D, G: PyTorch models for the discriminator and generator\n",
    "    - D_solver, G_solver: torch.optim Optimizers to use for training the\n",
    "      discriminator and generator.\n",
    "    - discriminator_loss, generator_loss: Functions to use for computing the generator and\n",
    "      discriminator loss, respectively.\n",
    "    - show_every: Show samples after every show_every iterations.\n",
    "    - batch_size: Batch size to use for training.\n",
    "    - noise_size: Dimension of the noise to use as input to the generator.\n",
    "    - num_epochs: Number of epochs over the training dataset to use for training.\n",
    "    \"\"\"\n",
    "    iter_count = 0\n",
    "    for epoch in range(num_epochs):\n",
    "        for x, _ in loader_train:\n",
    "            if len(x) != batch_size:\n",
    "                continue\n",
    "            D_solver.zero_grad()\n",
    "            real_data = x.type(dtype)\n",
    "            logits_real = D(2* (real_data - 0.5)).type(dtype)\n",
    "\n",
    "            g_fake_seed = sample_noise(batch_size, noise_size).type(dtype)\n",
    "            fake_images = G(g_fake_seed).detach()\n",
    "            logits_fake = D(fake_images.view(batch_size, 1, 28, 28))\n",
    "\n",
    "            d_total_error = discriminator_loss(logits_real, logits_fake)\n",
    "            d_total_error.backward()        \n",
    "            D_solver.step()\n",
    "\n",
    "            G_solver.zero_grad()\n",
    "            g_fake_seed = sample_noise(batch_size, noise_size).type(dtype)\n",
    "            fake_images = G(g_fake_seed)\n",
    "\n",
    "            gen_logits_fake = D(fake_images.view(batch_size, 1, 28, 28))\n",
    "            g_error = generator_loss(gen_logits_fake)\n",
    "            g_error.backward()\n",
    "            G_solver.step()\n",
    "\n",
    "            if (iter_count % show_every == 0):\n",
    "                print('Iter: {}, D: {:.4}, G:{:.4}'.format(iter_count,d_total_error.item(),g_error.item()))\n",
    "                imgs_numpy = fake_images.data.cpu().numpy()\n",
    "                show_images(imgs_numpy[0:16])\n",
    "                plt.show()\n",
    "                print()\n",
    "            iter_count += 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这并不难，对吧?在低100s的迭代中，你应该看到黑色的背景，当你接近迭代1000时，模糊的形状，和象样的形状，当我们超过3000时，其中大约一半将是清晰可识别的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-02-26T13:17:42.273421Z",
     "start_time": "2020-02-26T13:17:41.533154Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "invalid index of a 0-dim tensor. Use tensor.item() to convert a 0-dim tensor to a Python number",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-22-736eabd42f5d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[0mG_solver\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mget_optimizer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mG\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     10\u001b[0m \u001b[1;31m# Run it!\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 11\u001b[1;33m \u001b[0mrun_a_gan\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mD\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mG\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mD_solver\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mG_solver\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdiscriminator_loss\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mgenerator_loss\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m<ipython-input-21-e9b0df7f2ed6>\u001b[0m in \u001b[0;36mrun_a_gan\u001b[1;34m(D, G, D_solver, G_solver, discriminator_loss, generator_loss, show_every, batch_size, noise_size, num_epochs)\u001b[0m\n\u001b[0;32m     42\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     43\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0miter_count\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0mshow_every\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 44\u001b[1;33m                 \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Iter: {}, D: {:.4}, G:{:.4}'\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0miter_count\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0md_total_error\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mg_error\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     45\u001b[0m                 \u001b[0mimgs_numpy\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfake_images\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcpu\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     46\u001b[0m                 \u001b[0mshow_images\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mimgs_numpy\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;36m16\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mIndexError\u001b[0m: invalid index of a 0-dim tensor. Use tensor.item() to convert a 0-dim tensor to a Python number"
     ]
    }
   ],
   "source": [
    "# Make the discriminator\n",
    "D = discriminator().type(dtype)\n",
    "\n",
    "# Make the generator\n",
    "G = generator().type(dtype)\n",
    "\n",
    "# Use the function you wrote earlier to get optimizers for the Discriminator and the Generator\n",
    "D_solver = get_optimizer(D)\n",
    "G_solver = get_optimizer(G)\n",
    "# Run it!\n",
    "run_a_gan(D, G, D_solver, G_solver, discriminator_loss, generator_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Least Squares GAN\n",
    "We'll now look at [Least Squares GAN](https://arxiv.org/abs/1611.04076), a newer, more stable alernative to the original GAN loss function. For this part, all we have to do is change the loss function and retrain the model. We'll implement equation (9) in the paper, with the generator loss:\n",
    "$$\\ell_G  =  \\frac{1}{2}\\mathbb{E}_{z \\sim p(z)}\\left[\\left(D(G(z))-1\\right)^2\\right]$$\n",
    "and the discriminator loss:\n",
    "$$ \\ell_D = \\frac{1}{2}\\mathbb{E}_{x \\sim p_\\text{data}}\\left[\\left(D(x)-1\\right)^2\\right] + \\frac{1}{2}\\mathbb{E}_{z \\sim p(z)}\\left[ \\left(D(G(z))\\right)^2\\right]$$\n",
    "\n",
    "\n",
    "**HINTS**: Instead of computing the expectation, we will be averaging over elements of the minibatch, so make sure to combine the loss by averaging instead of summing. When plugging in for $D(x)$ and $D(G(z))$ use the direct output from the discriminator (`scores_real` and `scores_fake`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def ls_discriminator_loss(scores_real, scores_fake):\n",
    "    \"\"\"\n",
    "    Compute the Least-Squares GAN loss for the discriminator.\n",
    "    \n",
    "    Inputs:\n",
    "    - scores_real: PyTorch Variable of shape (N,) giving scores for the real data.\n",
    "    - scores_fake: PyTorch Variable of shape (N,) giving scores for the fake data.\n",
    "    \n",
    "    Outputs:\n",
    "    - loss: A PyTorch Variable containing the loss.\n",
    "    \"\"\"\n",
    "    loss = None\n",
    "    return loss\n",
    "\n",
    "def ls_generator_loss(scores_fake):\n",
    "    \"\"\"\n",
    "    Computes the Least-Squares GAN loss for the generator.\n",
    "    \n",
    "    Inputs:\n",
    "    - scores_fake: PyTorch Variable of shape (N,) giving scores for the fake data.\n",
    "    \n",
    "    Outputs:\n",
    "    - loss: A PyTorch Variable containing the loss.\n",
    "    \"\"\"\n",
    "    loss = None\n",
    "    return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before running a GAN with our new loss function, let's check it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def test_lsgan_loss(score_real, score_fake, d_loss_true, g_loss_true):\n",
    "    d_loss = ls_discriminator_loss(score_real, score_fake)\n",
    "    g_loss = ls_generator_loss(score_fake)\n",
    "    print(\"Maximum error in d_loss: %g\"%rel_error(d_loss_true, d_loss))\n",
    "    print(\"Maximum error in g_loss: %g\"%rel_error(g_loss_true, g_loss))\n",
    "\n",
    "test_lsgan_loss(answers['logits_real'], answers['logits_fake'],\n",
    "                answers['d_loss_lsgan_true'], answers['g_loss_lsgan_true'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "D_LS = discriminator().type(dtype)\n",
    "G_LS = generator().type(dtype)\n",
    "\n",
    "D_LS_solver = get_optimizer(D_LS)\n",
    "G_LS_solver = get_optimizer(G_LS)\n",
    "\n",
    "run_a_gan(D_LS, G_LS, D_LS_solver, G_LS_solver, ls_discriminator_loss, ls_generator_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# INLINE QUESTION 1\n",
    "Describe how the visual quality of the samples changes over the course of training. Do you notice anything about the distribution of the samples? How do the results change across different training runs?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "TODO: YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Deeply Convolutional GANs\n",
    "In the first part of the notebook, we implemented an almost direct copy of the original GAN network from Ian Goodfellow. However, this network architecture allows no real spatial reasoning. It is unable to reason about things like \"sharp edges\" in general because it lacks any convolutional layers. Thus, in this section, we will implement some of the ideas from [DCGAN](https://arxiv.org/abs/1511.06434), where we use convolutional networks \n",
    "\n",
    "#### Discriminator\n",
    "We will use a discriminator inspired by the TensorFlow MNIST classification tutorial, which is able to get above 99% accuracy on the MNIST dataset fairly quickly. \n",
    "* Reshape into image tensor (Use Unflatten!)\n",
    "* 32 Filters, 5x5, Stride 1, Leaky ReLU(alpha=0.01)\n",
    "* Max Pool 2x2, Stride 2\n",
    "* 64 Filters, 5x5, Stride 1, Leaky ReLU(alpha=0.01)\n",
    "* Max Pool 2x2, Stride 2\n",
    "* Flatten\n",
    "* Fully Connected size 4 x 4 x 64, Leaky ReLU(alpha=0.01)\n",
    "* Fully Connected size 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def build_dc_classifier():\n",
    "    \"\"\"\n",
    "    Build and return a PyTorch model for the DCGAN discriminator implementing\n",
    "    the architecture above.\n",
    "    \"\"\"\n",
    "    return nn.Sequential(\n",
    "        ###########################\n",
    "        ######### TO DO ###########\n",
    "        ###########################\n",
    "        Unflatten(batch_size, 1, 28, 28),\n",
    "    )\n",
    "\n",
    "data = Variable(loader_train.__iter__().next()[0]).type(dtype)\n",
    "b = build_dc_classifier().type(dtype)\n",
    "out = b(data)\n",
    "print(out.size())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check the number of parameters in your classifier as a sanity check:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def test_dc_classifer(true_count=1102721):\n",
    "    model = build_dc_classifier()\n",
    "    cur_count = count_params(model)\n",
    "    if cur_count != true_count:\n",
    "        print('Incorrect number of parameters in generator. Check your achitecture.')\n",
    "    else:\n",
    "        print('Correct number of parameters in generator.')\n",
    "\n",
    "test_dc_classifer()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Generator\n",
    "For the generator, we will copy the architecture exactly from the [InfoGAN paper](https://arxiv.org/pdf/1606.03657.pdf). See Appendix C.1 MNIST. See the documentation for [tf.nn.conv2d_transpose](https://www.tensorflow.org/api_docs/python/tf/nn/conv2d_transpose). We are always \"training\" in GAN mode. \n",
    "* Fully connected of size 1024, ReLU\n",
    "* BatchNorm\n",
    "* Fully connected of size 7 x 7 x 128, ReLU\n",
    "* BatchNorm\n",
    "* Reshape into Image Tensor\n",
    "* 64 conv2d^T filters of 4x4, stride 2, 'same' padding, ReLU\n",
    "* BatchNorm\n",
    "* 1 conv2d^T filter of 4x4, stride 2, 'same' padding, TanH\n",
    "* Should have a 28x28x1 image, reshape back into 784 vector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def build_dc_generator(noise_dim=NOISE_DIM):\n",
    "    \"\"\"\n",
    "    Build and return a PyTorch model implementing the DCGAN generator using\n",
    "    the architecture described above.\n",
    "    \"\"\"\n",
    "    return nn.Sequential(\n",
    "        ###########################\n",
    "        ######### TO DO ###########\n",
    "        ###########################\n",
    "    )\n",
    "\n",
    "test_g_gan = build_dc_generator().type(dtype)\n",
    "test_g_gan.apply(initialize_weights)\n",
    "\n",
    "fake_seed = Variable(torch.randn(batch_size, NOISE_DIM)).type(dtype)\n",
    "fake_images = test_g_gan.forward(fake_seed)\n",
    "fake_images.size()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check the number of parameters in your generator as a sanity check:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def test_dc_generator(true_count=6580801):\n",
    "    model = build_dc_generator(4)\n",
    "    cur_count = count_params(model)\n",
    "    if cur_count != true_count:\n",
    "        print('Incorrect number of parameters in generator. Check your achitecture.')\n",
    "    else:\n",
    "        print('Correct number of parameters in generator.')\n",
    "\n",
    "test_dc_generator()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "D_DC = build_dc_classifier().type(dtype) \n",
    "D_DC.apply(initialize_weights)\n",
    "G_DC = build_dc_generator().type(dtype)\n",
    "G_DC.apply(initialize_weights)\n",
    "\n",
    "D_DC_solver = get_optimizer(D_DC)\n",
    "G_DC_solver = get_optimizer(G_DC)\n",
    "\n",
    "run_a_gan(D_DC, G_DC, D_DC_solver, G_DC_solver, discriminator_loss, generator_loss, num_epochs=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# INLINE QUESTION 2\n",
    "What differences do you see between the DCGAN results and the original GAN results?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "TODO: YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extra Credit \n",
    "** Be sure you don't destroy your results above, but feel free to copy+paste code to get results below **\n",
    "* For a small amount of extra credit, you can implement additional new GAN loss functions below, provided they converge. See AFI, BiGAN, Softmax GAN, Conditional GAN, InfoGAN, etc. \n",
    "* Likewise for an improved architecture or using a convolutional GAN (or even implement a VAE)\n",
    "* For a bigger chunk of extra credit, load the CIFAR10 data (see last assignment) and train a compelling generative model on CIFAR-10\n",
    "* Something new/cool.\n",
    "\n",
    "#### Describe what you did here\n",
    "** TBD **"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "nbTranslate": {
   "displayLangs": [
    "*"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "fr",
   "useGoogleTranslate": true
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
